'''
Created on Jun 11, 2011

@author: Igor
'''

from lib.dbobjects import Explanation, Athlete, \
        RESULTS_DISPLAYED, ATHLETES_STORED, DAILY_BUDGET

BIG_NUMBER = 1000
SMALL_NUMBER = 0.001
MIN_CPC = 5

def cr_top_athletes(stats):
    explanation = Explanation.all().get()
    explanation.title="This auction uses CTR by position to correct for" + \
        " the disadvantages of the current method."
    winners = []
    athletes = Athlete.all().filter('out_of_budget =', False).fetch(ATHLETES_STORED)
    for athlete in athletes:
        clicks = sum(athlete.clicks)
        if athlete.new:
            product = athlete.cpc * BIG_NUMBER + athlete.cpc
        else:
            product = athlete.cpc * BIG_NUMBER * clicks / athlete.ec + athlete.cpc
        winners.append([athlete.name, product, athlete.cpc, clicks, 
                        athlete.ec, athlete.new, athlete.id])
    winners.sort(key=lambda x: x[1], reverse=True)
    
    names = []
    ids = []
    comments = []
    
    for i in xrange(RESULTS_DISPLAYED):
        names.append(winners[i][0])
        ids.append(winners[i][6])
        if winners[i][5]:
            comments.append("The athlete is in place %d because he has CPC=" %
                            (i+1) + "%d, and Clicks/ExpectedClicks " %
                            winners[i][2] + "estimated" +" as 1.")
        else:
            comments.append("The athlete is in place %d because he has CPC=" %
                            (i+1) + "%d, and Clicks/ExpectedClicks=(%d/%s)." % 
                            (winners[i][2], winners[i][3], str(winners[i][4])))
    names.append("None of these")
    stats.top_names = names
    
    costs = RESULTS_DISPLAYED * [0]
    costs[RESULTS_DISPLAYED-1] = winners[RESULTS_DISPLAYED-1][2]
    comments[RESULTS_DISPLAYED-1] += "  Since the athlete is last, he will pay full CPC of %d." % \
            costs[RESULTS_DISPLAYED-1]
    stats.max_cpc_times += 1
    for i in xrange(RESULTS_DISPLAYED-1):
        current_index = RESULTS_DISPLAYED - 2 - i
        if winners[current_index+1][5] and winners[current_index][5]:
            costs[current_index] = winners[current_index+1][2] + 1
            comments[current_index] += "  The formula is %d * 1 / 1 + 1." % \
                    (winners[current_index+1][2])
        elif winners[current_index+1][5]:
            costs[current_index] = int(winners[current_index+1][2] * winners[current_index][4] / 
                        winners[current_index][3]) + 1
            comments[current_index] += "  The formula is %d * 1 / (%d/%s) + 1." \
                    % (winners[current_index+1][2], winners[current_index][3],
                       str(winners[current_index][4]))
        elif winners[current_index][5]:
            costs[current_index] = int(winners[current_index+1][2] * winners[current_index+1][3] /
                winners[current_index+1][4]) + 1
            comments[current_index] += "  The formula is %d * (%d/%s) / 1 + 1." % (
                    winners[current_index+1][2], winners[current_index+1][3], 
                    str(winners[current_index+1][4]))
        elif winners[current_index][3] < SMALL_NUMBER:
            costs[current_index] = costs[current_index+1] + 1
            comments[current_index] += "  The formula is %d * (%d/%s) / (%d/%s) + 1." % \
                    (winners[current_index+1][2], winners[current_index+1][3], 
                    str(winners[current_index+1][4]), winners[current_index][3], 
                    str(winners[current_index][4]))
            comments[current_index] += "  Since both clicks are zero, we just add one."
        else:
            costs[current_index] = int(winners[current_index+1][2] * winners[current_index+1][3] *
                winners[current_index][4] / winners[current_index][3] / 
                winners[current_index+1][4]) + 1
            comments[current_index] += "  The formula is %d * (%d/%s) / (%d/%s) + 1." % (
                    winners[current_index+1][2], winners[current_index+1][3], 
                    str(winners[current_index+1][4]), winners[current_index][3], 
                    str(winners[current_index][4]))
        if costs[current_index] >= winners[current_index][2]:
            costs[current_index] = winners[current_index][2]
            comments[current_index] += "  The athlete will pay his max CPC of %d" % \
                    (winners[current_index][2])
            stats.max_cpc_times += 1
        elif costs[current_index] < MIN_CPC:
            costs[current_index] = MIN_CPC
            comments[current_index] += "  The athlete will pay MIN_CPC of %d" % \
                    (MIN_CPC)
            stats.min_cpc_times += 1
        else:
            comments[current_index] += "  The athlete will pay %d according to the formula." % \
                    (costs[current_index])
                        
    stats.costs = costs
    explanation.comments = comments
    explanation.put()
    return ids